package com.game.units {
	import com.game.data.Data;
	import com.game.utils.TowerType;
	import flash.display.Shape;
	import flash.geom.Point;
	public class Enemy extends Shape {
		private var offset:Point=new Point();
		private var _speed:Number=0;
		private var _motionSpeed:Number=0;
		private var _speedRestoreCounter:int=0;
		private var _health:int;
		public var size:int=Data.STEP;
		public var padding:int=Data.IMAGE_PADDING;
		public var readyForRemoval:Boolean=false;
		private var pathArray:Array;
		private var pathCounter:int=0;
		private var _lastPoint:Point=new Point();
		private var _nextPoint:Point=new Point();
		private var _walkingStep:Point=new Point();
		private var _reward:int;
		private var _releaseDelay:int;
		private var _isAir:Boolean;
		private var _type:int=0;
		private var enemyGraphics:EnemyGraphics;
		private var enemyHealth:EnemyHealth;
		public function Enemy() {
			enemyGraphics=new EnemyGraphics(this.graphics);
			enemyHealth=new EnemyHealth(this.graphics);
		}
		public function init(type:int, air:Boolean, arr:Array, speed:Number, health:int, reward:int, releaseDelay:int):void {
			_reward=reward;
			_speed=speed;
			_motionSpeed=_speed;
			_type=type;
			_isAir=air;
			this.health=health;
			pathArray=arr.reverse();
			pathCounter=0;
			this.x=(pathArray[pathCounter].pos.x + 0.5) * Data.STEP;
			this.y=(pathArray[pathCounter].pos.y + 0.5) * Data.STEP;
			readyForRemoval=false;
			_speedRestoreCounter=Data.SPEED_RESTORE_COUNTER;
			_releaseDelay=releaseDelay;
			this.visible=false;
			enemyGraphics.init(type);
			enemyGraphics.redraw();
			enemyHealth.init(health);
			calculateWalkingStep();
		}
		private function calculateWalkingStep():void {
			_lastPoint.x=pathArray[pathCounter].pos.x;
			_lastPoint.y=pathArray[pathCounter].pos.y;
			_nextPoint.x=pathArray[pathCounter + 1].pos.x;
			_nextPoint.y=pathArray[pathCounter + 1].pos.y;
			_walkingStep.x=(_nextPoint.x - _lastPoint.x) * Data.STEP;
			_walkingStep.y=(_nextPoint.y - _lastPoint.y) * Data.STEP;
			this.x=(_lastPoint.x + 0.5) * Data.STEP;
			this.y=(_lastPoint.y + 0.5) * Data.STEP;
			this.enemyGraphics.turn(-Math.atan2(_walkingStep.x, _walkingStep.y));
		}
		public function move():void {
			_releaseDelay--;
			if (_releaseDelay > 0) {
				return;
			}
			if (!this.visible) {
				this.visible=true;
			}
			_speedRestoreCounter--;
			if (_speedRestoreCounter < 0) {
				_speedRestoreCounter=-1;
				_motionSpeed=_speed;
			}
			x+=_walkingStep.x * _motionSpeed*4;
			y+=_walkingStep.y * _motionSpeed*4;
			this.enemyGraphics.move();
			this.enemyGraphics.redraw();
			checkPointGet();
		}
		private function checkPointGet():void {
			var dltX:Number=(x - (Data.STEP / 2)) - _nextPoint.x * Data.STEP
			var dltY:Number=(y - (Data.STEP / 2)) - _nextPoint.y * Data.STEP
			var dlt:Number=(dltX * dltX) + (dltY * dltY);
			var dist:Number=(_walkingStep.x * _motionSpeed) * (_walkingStep.x * _motionSpeed) + (_walkingStep.y * _motionSpeed) * (_walkingStep.y * _motionSpeed)
			if (dlt <= dist) {
				this.pathCounter++;
				if (this.pathCounter < pathArray.length - 1) {
					calculateWalkingStep();
				} else {
					_reward=0;
					readyForRemoval=true;
				}
			}
		}
		public function setPath(arr:Array):void {
			//reverse the array in the correct order, cut till starting point
			arr.reverse();
			pathArray.splice(this.pathCounter + 1);
			pathArray=pathArray.concat(arr);
		}
		public function isHit(type:TowerType, damage:Number):void {
			if (_releaseDelay > 0) {
				return;
			}
			if (type == TowerType.SLOW) {
				_speedRestoreCounter=Data.SPEED_RESTORE_COUNTER;
				_motionSpeed=_speed / damage;
			} else {
				health-=damage;
				if (health <= 0) {
					readyForRemoval=true;
				}
			}
		}
		public function set speed(value:Number):void {
			_speed=value;
			_motionSpeed=_speed;
		}
		public function get health():int {
			return _health;
		}
		public function set health(value:int):void {
			_health=value;
			enemyHealth.update(_health);
		}
		public function get nextPoint():Point {
			return _nextPoint;
		}
		public function get reward():int {
			return _reward;
		}
		public function get isAir():Boolean {
			return _isAir;
		}
		public function get type():int {
			return _type;
		}
	}
}